home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
comm2
/
kms20src.lha
/
KMSC
/
inout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-05
|
40KB
|
1,527 lines
/**********************************
* KMS *
**********************************
* ©1993 by BlackMagic Software *
**********************************
* *
**********************************/
#include <KMS/KMS.h>
#include <KMS/KMS_devlib.h>
#include <KMS/KMS_intui.h>
Prototype VOID FlushInput(VOID);
Prototype VOID SetTimer(ULONG, ULONG);
Prototype UBYTE Print(STRPTR, UWORD);
Prototype UBYTE BreakCheck(UWORD);
Prototype VOID XOff(VOID);
Prototype VOID OutChar(TEXT);
Prototype VOID OutBuffer(BPTR, TEXT);
Prototype VOID OutString(BPTR, STRPTR);
Prototype LONG CmdInput(STRPTR, UWORD, STRPTR, STRPTR, UWORD, UWORD);
Prototype BOOL PlopCheck(UBYTE, UWORD);
Prototype WORD InKey(WORD);
Prototype WORD InKeyNew(WORD);
Prototype TEXT ReadKey(VOID);
Prototype UWORD CheckCSI(TEXT);
Prototype BOOL StringSearch(STRPTR, STRPTR);
Prototype VOID DoFKey(UWORD);
Prototype ULONG MakeTime(STRPTR, time_t, time_t);
Prototype VOID CursorOn(VOID);
Prototype VOID CursorOff(VOID);
Prototype VOID DelInputChar(UWORD);
Prototype VOID InsInputChar(UWORD);
Prototype VOID ChatOut(STRPTR, UWORD);
Prototype VOID Error(STRPTR);
extern VOID KPrintF(APTR, ...);
/*****************************
* Externe Globale Variablen *
*****************************/
extern struct timerequest *Time_Request;
extern struct MsgPort *Timer_Port;
extern struct DosPacket *InputPacket;
extern struct KMSBase *KMSBase;
extern struct LocalConfig *KMS_LC;
extern ULONG TimerSignal, RexxSignal, InputSignal;
extern UWORD AutoAct;
extern UBYTE LazyCount;
extern STRPTR PPArg;
extern UBYTE ShutDown;
extern BPTR StdErr;
/*********************
* Globale Variablen *
*********************/
UBYTE Plop = 0;
BOOL Spying = FALSE;
/****************************
* Lese-Kanal leeren *
****************************
* I: --- *
* O: --- *
****************************/
/// "FlushInput"
VOID FlushInput(VOID)
{
TEXT buff[128];
WORD len;
while(WaitForChar(KMS_LC->InHandle, 0) == DOSTRUE)
{
len = Read(KMS_LC->InHandle, buff, sizeof(buff));
SetSignal(0, SIGBREAKF_CTRL_C);
if (len <= 0)
{
/* EOF/Fehler: Plop und raus */
Plop = PLOP_BREAKC;
return;
}
}
}
///
/************************************
* Timer initialisieren und starten *
************************************
* I: Sekunden und Mikrosekunden *
* O: --- *
************************************/
/// "SetTimer"
VOID SetTimer(ULONG secs, ULONG micros)
{
Time_Request->tr_node.io_Command = TR_ADDREQUEST;
Time_Request->tr_node.io_Flags = 0;
Time_Request->tr_time.tv_secs = secs;
Time_Request->tr_time.tv_micro = micros;
SendIO((struct IORequest *)Time_Request);
}
///
/***************************************
* Standard Textausgabe (Zeichenkette) *
***************************************
* I: String, Flags *
* O: CTRL-X, CTRL-C oder 0 *
***************************************/
/// "Print"
UBYTE Print(STRPTR string, UWORD flags)
{
UWORD i = 0;
UBYTE c;
if (string)
{
while(string[i])
OutChar(string[i++]);
if (!(flags & PF_NOBRK) && (c = BreakCheck(flags)))
{
OutChar('\r');
OutChar('\n');
return c;
}
}
if (!(flags & PF_NOLF))
{
OutChar('\r');
OutChar('\n');
}
else
OutChar(0);
return 0;
}
///
/*****************************************
* Auf CTRL-X CTRL-C CTRL-S prüfen *
*****************************************
* I: Flags PF_CTRLC|PF_CTRLX|PF_NOCTRLS *
* O: ^X, ^C oder 0 *
*****************************************/
/// "BreakCheck"
UBYTE BreakCheck(UWORD flags)
{
TEXT c = 0;
if (c = ReadKey())
{
switch(c)
{
case 3:
if (!(flags & PF_CTRLC))
c = 0;
break;
case 19:
if (!(flags & PF_NOCTRLS))
XOff();
c = 0;
break;
case 24:
if (!(flags & PF_CTRLX))
c = 0;
break;
default:
c = 0;
}
}
return c;
}
///
/***************************************
* CTRLS-Pause *
***************************************
* I: --- *
* O: --- *
***************************************/
/// "XOff"
VOID XOff(VOID)
{
OutChar(0);
InKey(KMSBase->XOFFTimeout);
}
///
/*************************************
* Senden eines Zeichens *
*************************************
* I: Zeichen *
* O: --- *
*************************************/
/// "OutChar"
VOID OutChar(TEXT c)
{
OutBuffer(KMS_LC->OutHandle, KMSBase->CharOut[KMS_LC->Session.CurrentUser->UserData.CharSet][c]);
}
///
/****************************************
* Ausgabe-Pufferung *
****************************************
* I: Zeichen *
* O: --- *
****************************************/
/// "OutBuffer"
TEXT OutputBuffer[LEN_OUTPUT+1];
VOID OutBuffer(BPTR handle, TEXT c)
{
static UWORD pos = 0;
OutputBuffer[pos++] = c;
if (c == '\0' || c == '\n' || pos == LEN_OUTPUT)
{
OutputBuffer[pos] = '\0';
OutString(handle, OutputBuffer);
pos = 0;
}
}
///
/****************************************
* Standard Textausgabe, Zeichenkette *
****************************************
* I: Zeichenkette *
* O: --- *
****************************************/
/// "OutString"
VOID OutString(BPTR handle, STRPTR string)
{
Write(handle, string, strlen(string));
if (Spying)
Write(KMS_LC->SpyHandle, string, strlen(string));
}
///
/***************************************
* Einlesen der nächsten Kommandozeile *
***************************************
* I: Prompt, Excludes, Default-Text, *
* I: Länge, Flags *
* O: -9 : ShutDown *
* O: -1 : Eingabe-Timeout *
* O: 0 : Leere Eingabe *
* O: +n : Länge/Wert der Eingabe *
***************************************/
/// "CmdInput"
LONG CmdInput(STRPTR prompt, UWORD promptnum, STRPTR excludes, STRPTR deftxt, UWORD length, UWORD flags)
{
WORD c;
UWORD buffpos, crspos, result;
BOOL capsflag = FALSE, weiter = TRUE;
KMS_LC->Session.Refresh = FALSE;
struct HistoryNode *hpoint = KMS_LC->Session.HistPoint;
if (hpoint->Node.mln_Succ)
hpoint = hpoint->Node.mln_Succ;
buffpos = 0;
crspos = 0;
result = 0;
*KMS_LC->Session.InputBuffer = '\0';
if (length > LEN_CMDINPUT)
length = LEN_CMDINPUT;
if (deftxt && strlen(deftxt) > length)
deftxt[length] = '\0';
PPArg = deftxt;
if (promptnum && (flags & INF_PROMPT))
SysMsg(promptnum);
else if (prompt)
ParsePrint(prompt, PF_NOLF|PF_NOBRK);
PPArg = NULL;
if (deftxt && (flags & INF_DEFBUF))
{
strcpy(KMS_LC->Session.InputBuffer, deftxt);
buffpos = strlen(KMS_LC->Session.InputBuffer);
crspos = buffpos;
Print(KMS_LC->Session.InputBuffer, PF_NOLF|PF_NOBRK);
}
CursorOn();
while(weiter)
{
c = InKey(-KMSBase->InputTimeout);
if (c > 0) /* Gültiges Zeichen empfangen */
{
result = 0;
if (!buffpos && (flags & INF_MSGMODE)
&& (c >= '1' && c <= '9' && KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI))
{
switch(c)
{
case '8': /* CRS UP */
result = 22;
break;
case '2': /* CRS DOWN */
result = 23;
break;
case '3': /* SHIFT CRS DOWN */
result = 27;
break;
case '1': /* SHIFT CRS UP */
result = 26;
break;
case '9': /* SHIFT CRS RIGHT */
result = 29;
break;
case '7': /* SHIFT CRS LEFT */
result = 28;
break;
case '6': /* CRS RIGHT */
result = 24;
break;
case '4': /* CRS LEFT */
result = 25;
break;
default:
result = 0;
}
}
if (result != 0 || c == 0x9b || c == 0x1b)
{
if ((result != 0 || (result = CheckCSI((TEXT)c))) && (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI))
{
/* CSI/ESC empfangen -> Prüfen auf Funktions-/Cursortaste */
switch(result)
{
case 22: /* CRS UP */
if (flags & INF_HISTORY)
{
UWORD n;
CursorOff();
for(n = crspos; n > 0; n--)
OutChar(8);
for(n = buffpos; n > 0; n--)
OutChar(' ');
for(n = buffpos; n > 0; n--)
OutChar(8);
OutChar(0);
*KMS_LC->Session.InputBuffer = '\0';
if (hpoint->Node.mln_Pred)
{
hpoint = hpoint->Node.mln_Pred;
if (hpoint->Node.mln_Pred)
{
strcpy(KMS_LC->Session.InputBuffer, hpoint->Cmd);
Print(KMS_LC->Session.InputBuffer, PF_NOLF|PF_NOBRK);
}
}
buffpos = strlen(KMS_LC->Session.InputBuffer);
crspos = buffpos;
CursorOn();
}
else if (flags & INF_CRSMODE)
{
strcpy(KMS_LC->Session.InputBuffer, "<CRS_UP>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
break;
case 23: /* CRS DOWN */
if (flags & INF_HISTORY)
{
UWORD n;
CursorOff();
for(n = crspos; n > 0; n--)
OutChar(8);
for(n = buffpos; n > 0; n--)
OutChar(' ');
for(n = buffpos; n > 0; n--)
OutChar(8);
OutChar(0);
*KMS_LC->Session.InputBuffer = '\0';
if (hpoint->Node.mln_Succ)
{
hpoint = hpoint->Node.mln_Succ;
if (hpoint->Node.mln_Succ)
{
strcpy(KMS_LC->Session.InputBuffer, hpoint->Cmd);
Print(KMS_LC->Session.InputBuffer, PF_NOLF|PF_NOBRK);
}
}
buffpos = strlen(KMS_LC->Session.InputBuffer);
crspos = buffpos;
CursorOn();
}
else if (flags & INF_CRSMODE)
{
strcpy(KMS_LC->Session.InputBuffer, "<CRS_DN>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
break;
case 24: /* CRS RIGHT */
if (!buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_CRS_RIGHT;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (!buffpos && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<CRS_RT>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
else if (crspos < buffpos)
{
OutChar(0x1b);
OutChar('[');
OutChar('C');
OutChar(0);
crspos++;
}
break;
case 25: /* CRS LEFT */
if (!buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_CRS_LEFT;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (!buffpos && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<CRS_LT>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
else if (crspos)
{
OutChar(0x1b);
OutChar('[');
OutChar('D');
OutChar(0);
crspos--;
}
break;
case 26: /* SHIFT CRS UP */
if (!buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_SHIFT_CRS_UP;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (!buffpos && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<SH_CRS_UP>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
break;
case 27: /* SHIFT CRS DOWN */
if (!buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_SHIFT_CRS_DOWN;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (!buffpos && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<SH_CRS_DN>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
break;
case 28: /* SHIFT CRS LEFT */
if (!buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_LIST_CURRENT;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (!buffpos && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<SH_CRS_LT>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
else while(crspos)
{
OutChar(0x1b);
OutChar('[');
OutChar('D');
OutChar(0);
crspos--;
}
break;
case 29: /* SHIFT CRS RIGHT */
if (!buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_SHIFT_CRS_RIGHT;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (!buffpos && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<SH_CRS_RT>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
else while(crspos < buffpos)
{
OutChar(0x1b);
OutChar('[');
OutChar('C');
OutChar(0);
crspos++;
}
break;
default:
DoFKey(result);
break;
}
}
else if (c == 0x1b && (flags & INF_CRSMODE))
{
strcpy(KMS_LC->Session.InputBuffer, "<ESC>");
result = 1;
buffpos = 0;
crspos = 0;
weiter = FALSE;
}
}
else if (c == 8)
{
if (crspos)
{
/* BACKSPACE */
buffpos--;
crspos--;
if ((KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI) && !(flags & INF_NOINSERT))
{
OutChar(c);
OutChar(0x1b);
OutChar('[');
OutChar('P');
OutChar(0);
}
else
{
OutChar(c);
OutChar(' ');
OutChar(c);
OutChar(0);
}
DelInputChar(crspos);
}
}
else if (c == 127)
{
if (crspos < buffpos && (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI) && !(flags & INF_NOINSERT))
{
/* DELETE */
buffpos--;
OutChar(0x1b);
OutChar('[');
OutChar('P');
OutChar(0);
DelInputChar(crspos);
}
}
else if (c == 1)
{
/* Toggle Insert <-> Overstrike */
KMS_LC->Session.CurrentUser->UserData.Flags ^= UF_EDIT_INSERT;
}
else if (c == 24)
{
/* Ctrl-X: Input löschen */
UWORD n;
CursorOff();
for(n = crspos; n > 0; n--)
OutChar(8);
for(n = buffpos; n > 0; n--)
OutChar(' ');
for(n = buffpos; n > 0; n--)
OutChar(8);
OutChar(0);
*KMS_LC->Session.InputBuffer = '\0';
buffpos = 0;
crspos = 0;
CursorOn();
}
else if ((c == 32 || c == '\r' || c == '5') && !buffpos && (flags & INF_MSGMODE))
{
Print(NULL, 0);
AutoAct = ACTION_CRS_RIGHT;
*KMS_LC->Session.InputBuffer = '\0';
result = 0;
weiter = FALSE;
}
else if (c > 31
&& (buffpos < length || (crspos < buffpos && ((flags & INF_NOINSERT) || !(KMS_LC->Session.CurrentUser->UserData.Flags & UF_EDIT_INSERT))))
&& (!(flags & INF_NUMERIC) || (c >= 48 && c <= 57)))
{
/* Zeichen ausgeben und merken im KMS_LC->Session.InputBuffer */
if (flags & INF_SPECIAL)
{
if (!buffpos || c == 32 || c == '-')
capsflag = FALSE;
}
if ((flags & INF_UPCASE) || ((flags & INF_SPECIAL) && !capsflag))
{
c = toupper(c);
if ((flags & INF_SPECIAL) && c != 32 && c != '-')
capsflag = TRUE;
}
if (!excludes || (!strchr(excludes, c) && (flags & INF_EXCLUDE))
|| (strchr(excludes, c) && !(flags & INF_EXCLUDE)))
{
if (crspos < buffpos && !(flags & INF_NOINSERT) && (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EDIT_INSERT))
{
OutChar(0x1b);
OutChar('[');
OutChar('@');
InsInputChar(crspos);
}
if (flags & INF_HIDE)
OutChar('*');
else
OutChar(c);
OutChar(0);
KMS_LC->Session.InputBuffer[crspos++] = c;
if (crspos > buffpos || (!(flags & INF_NOINSERT) && (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EDIT_INSERT)))
{
buffpos++;
KMS_LC->Session.InputBuffer[buffpos] = '\0';
}
}
}
if (weiter)
{
if ((c == '\r' && (!(flags & INF_NOEMPTY) || buffpos))
|| ((flags & INF_FORCECR) && buffpos == length))
{
if (!(flags & INF_NOLF))
Print(NULL, 0);
KMS_LC->Session.InputBuffer[buffpos] = '\0';
if (flags & INF_NUMERIC)
result = atoi(KMS_LC->Session.InputBuffer);
else
result = strlen(KMS_LC->Session.InputBuffer);
weiter = FALSE;
}
}
}
else if (c == 0)
{
/* Nix gekommen oder ARexx-Msg wurde gerade abgearbeitet:
Evt. Eingabezeile refreshen */
if (KMS_LC->Session.Refresh)
{
CursorOff();
OutChar('\r');
PPArg = deftxt;
if (promptnum && (flags & INF_PROMPT))
SysMsg(promptnum);
else if (prompt)
ParsePrint(prompt, PF_NOLF|PF_NOBRK);
PPArg = NULL;
Print(KMS_LC->Session.InputBuffer, PF_NOLF|PF_NOBRK);
CursorOn();
KMS_LC->Session.Refresh = FALSE;
}
}
else if (c == -9)
{
/* ShutDown / Lock / Rexx-Logout */
Print(NULL, 0);
*KMS_LC->Session.InputBuffer = '\0';
CursorOff();
return -9;
}
else
{
/* Timeout aufgetreten */
CursorOff();
Print(NULL, 0);
LazyCount++;
if (!PlopCheck(LazyCount, flags))
return -1;
/* Wenn nicht Plop, erneute Eingabe */
PPArg = deftxt;
if (promptnum && (flags & INF_PROMPT))
SysMsg(promptnum);
else if (prompt)
ParsePrint(prompt, PF_NOLF|PF_NOBRK);
PPArg = NULL;
Print(KMS_LC->Session.InputBuffer, PF_NOLF|PF_NOBRK);
CursorOn();
}
}
CursorOff();
if (flags & INF_HISTORY)
{
buffpos--;
while(buffpos && KMS_LC->Session.InputBuffer[buffpos] == ' ')
KMS_LC->Session.InputBuffer[buffpos--] = '\0';
if (KMS_LC->Session.InputBuffer[buffpos] == ' ')
KMS_LC->Session.InputBuffer[buffpos] = '\0';
result = strlen(KMS_LC->Session.InputBuffer);
/* History-Eintrag */
if (*KMS_LC->Session.InputBuffer && (!KMS_LC->HistCount || stricmp(KMS_LC->Session.HistPoint->Cmd, KMS_LC->Session.InputBuffer)))
{
if (KMS_LC->HistCount < KMSBase->MaxHistCount)
{
if (hpoint = (struct HistoryNode *)AllocMem((ULONG)sizeof(struct HistoryNode), MEMF_PUBLIC|MEMF_CLEAR))
{
AddTail((struct List *)&KMS_LC->HistoryList, (struct Node *)hpoint);
KMS_LC->HistCount++;
}
}
else
{
hpoint = KMS_LC->HistoryList.mlh_Head;
RemHead((struct Node *)&KMS_LC->HistoryList);
AddTail((struct List *)&KMS_LC->HistoryList, (struct Node *)hpoint);
}
if (hpoint)
{
strcpy(hpoint->Cmd, KMS_LC->Session.InputBuffer);
KMS_LC->Session.HistPoint = hpoint;
}
}
}
if (deftxt && !(flags & INF_DEFBUF) && *KMS_LC->Session.InputBuffer == '\0')
{
strcpy(KMS_LC->Session.InputBuffer, deftxt);
if (flags & INF_NUMERIC)
result = atoi(KMS_LC->Session.InputBuffer);
else
result = strlen(KMS_LC->Session.InputBuffer);
}
return result;
}
///
/*************************************
* Timeout-Überprüfung *
*************************************
* I: >0, wenn Timout, Input-Flags *
* O: FALSE: ShutDown/Timeout *
* O: TRUE : Weitermachen *
*************************************/
/// "PlopCheck"
BOOL PlopCheck(UBYTE count, UWORD flags)
{
WORD timeleft;
static WORD merk = 0;
if (ShutDown == SHUTDOWN_IMMEDIATE || Plop)
return FALSE;
/* Timeout bei Input? */
if (count)
{
SysMsg(SYSEVENT);
if (count > KMSBase->InputTimeoutWarnings)
{
SysMsg(BIBI_SLEEPY);
Plop = PLOP_INTIMEOUT;
return FALSE;
}
else
SysMsg(WAKE_UP_PLEASE);
}
else
{
/* Prüfen der Verbindungszeit */
if (!KMS_LC->Session.MaxConnectTime) /* Ewig Zeit :-) */
return TRUE;
timeleft = KMS_LC->Session.MaxConnectTime - (MakeTime(NULL, KMS_LC->Session.LoginTime, 0) / 60);
if (timeleft <= 0)
{
SysMsg(SYSEVENT);
SysMsg(SYSTIME_EXCEEDED);
merk = 0;
Plop = PLOP_SYSTIMEOUT;
return FALSE;
}
else if (timeleft <= KMSBase->MaxConnectWarnings)
{
if (timeleft > 1 && timeleft != merk)
{
SysMsg(SYSEVENT);
SysMsg(X_MINUTES_LEFT);
}
else if (timeleft != merk)
{
SysMsg(SYSEVENT);
SysMsg(ONE_MINUTE_LEFT);
}
merk = timeleft;
}
}
return TRUE;
}
///
/***********************************
* Warten auf ein Zeichen (Unused) *
***********************************
* I: Timout-Zeit in Sekunden *
* O: Zeichen bzw. -1 für Timeout *
* O: -9 für ShutDown *
***********************************/
/// "InKeyNew"
WORD InKeyNew(WORD timeout)
{
TEXT c = 0;
ULONG insignal;
static BOOL timeractive = FALSE;
/* Im Lokalbetrieb soll es keine Timeouts geben */
if (KMS_LC->Device & DEV_CONSOLE)
timeout = 0;
/* Soll evt. weitergewartet werden? */
if (timeout < 0)
{
if (!timeractive)
timeout = -timeout;
else
timeout = 0;
}
/* Falls nötig, Input-Timer starten */
if (timeout)
{
InputPacket->dp_Arg1 = timeout * 1000000L;
SendPkt(InputPacket,
((struct FileHandle *)BADDR(KMS_LC->InHandle))->fh_Type,
InputPacket->dp_Link->mn_ReplyPort);
timeractive = TRUE;
}
while(1)
{
insignal = Wait(RexxSignal | InputSignal);
if ((insignal & InputSignal) == InputSignal)
{
GetMsg(InputPacket->dp_Link->mn_ReplyPort);
timeractive = FALSE;
if (InputPacket->dp_Res1 == DOSFALSE)
{
/* Nix gekommen, Break prüfen */
if (CheckSignal(SIGBREAKF_CTRL_C))
{
/* Plop */
Plop = PLOP_BREAKC;
return -9;
}
/* Timeout */
return -1;
}
else
{
/* Zeichen abholen */
if (Read(KMS_LC->InHandle, &c, 1) == 1)
{
c = KMSBase->CharIn[KMS_LC->Session.CurrentUser->UserData.CharSet][c];
if (c == 3)
SetSignal(0, SIGBREAKF_CTRL_C);
return (WORD)c;
}
else
{
/* Plop */
Plop = PLOP_BREAKC;
return -9;
}
}
}
if ((insignal & RexxSignal) == RexxSignal)
{
dispRexxPort();
/* Hier muesste ACTION_WAIT_CHAR abgebrochen werden!
Geht aber nicht! */
if (KMS_LC->Session.Refresh)
return 0;
if (ShutDown == SHUTDOWN_IMMEDIATE || KMS_LC->Locked == LOCK_IMMEDIATE || Plop)
return -9;
}
}
}
///
/***********************************
* Warten auf ein Zeichen *
***********************************
* I: Timout-Zeit in Sekunden *
* O: Zeichen bzw. -1 für Timeout *
* O: -9 für ShutDown *
***********************************/
/// "InKey"
WORD InKey(WORD timeset)
{
static UWORD timeout = 0;
TEXT c = 0;
BOOL endless;
if (timeset >= 0)
timeout = timeset;
else if (timeout == 0)
timeout = -timeset;
/* Im Lokalbetrieb soll es keine Timeouts geben */
if (KMS_LC->Device & DEV_CONSOLE)
endless = TRUE;
else
endless = FALSE;
while(endless || timeout)
{
/* 1s auf Zeichen warten */
if (WaitForChar(KMS_LC->InHandle, 1000000L) == DOSFALSE)
{
/* Nix gekommen, Break prüfen und Rexx-Port abfragen */
if (CheckSignal(SIGBREAKF_CTRL_C))
Plop = PLOP_BREAKC;
else
{
dispRexxPort();
if (KMS_LC->Session.Refresh && timeset < 0)
return 0;
}
if (ShutDown == SHUTDOWN_IMMEDIATE || KMS_LC->Locked == LOCK_IMMEDIATE || Plop)
return -9;
}
else
{
/* Zeichen abholen */
if (Read(KMS_LC->InHandle, &c, 1) == 1)
{
c = KMSBase->CharIn[KMS_LC->Session.CurrentUser->UserData.CharSet][c];
if (c == 3)
SetSignal(0, SIGBREAKF_CTRL_C);
timeout = 0;
return (WORD)c;
}
else
{
Plop = PLOP_BREAKC;
return -9;
}
}
timeout--;
}
/* Eingabetimeout */
return -1;
}
///
/**********************************
* Tastatur/Serialcheck *
**********************************
* I: --- *
* O: Zeichen bzw. 0 *
**********************************/
/// "ReadKey"
TEXT ReadKey(VOID)
{
TEXT c = 0;
if (WaitForChar(KMS_LC->InHandle, 0) == DOSFALSE)
{
if (CheckSignal(SIGBREAKF_CTRL_C))
Plop = PLOP_BREAKC;
return 0;
}
if (Read(KMS_LC->InHandle, &c, 1) == 1)
{
c = KMSBase->CharIn[KMS_LC->Session.CurrentUser->UserData.CharSet][c];
if (c == 3)
SetSignal(0, SIGBREAKF_CTRL_C);
return c;
}
else
{
Plop = PLOP_BREAKC;
return 0;
}
}
///
/*********************************************
* Prüfen auf Funktionstaste/Helptaste *
*********************************************
* I: --- *
* O: 1-20: F-Taste, 21: HELP, 22-26: Cursor *
*********************************************/
/// "CheckCSI"
UWORD CheckCSI(TEXT intro)
{
UWORD result;
TEXT c;
TEXT buff[10];
UWORD pos = 0;
BOOL ok = FALSE;
*buff = '\0';
if (intro != 0x1b)
ok = TRUE;
while(WaitForChar(KMS_LC->InHandle, 500000L)) /* max. 0,5 sec warten */
{
if (Read(KMS_LC->InHandle, &c, 1) != 1)
{
Plop = PLOP_BREAKC;
return 0;
}
if (!ok)
{
if (c == '[')
ok = TRUE;
else
return 0;
}
else
{
buff[pos++] = c;
buff[pos] = '\0';
}
/* Wurde Sondertaste gedrückt? */
if (!strcmp(buff, "?~"))
{
/* HELP-Taste */
return 21;
}
else if (*buff >= 'A' && *buff <= 'D')
{
/* Cursor-Taste */
return *buff-65+22;
}
else if (*buff == 'T')
{
/* SHIFT CURSOR UP */
return 26;
}
else if (*buff == 'S')
{
/* SHIFT CURSOR DOWN */
return 27;
}
else if (!strcmp(buff, " A"))
{
/* SHIFT CURSOR LEFT */
return 28;
}
else if (!strcmp(buff, " @"))
{
/* SHIFT CURSOR RIGHT */
return 29;
}
else if (pos > 0 && buff[pos-1] == '~')
{
/* Funktionstaste */
result = atoi(buff);
if (result >= 0 && result <= 19)
return result + 1;
else
return 0;
}
if (pos == 9)
return 0;
}
return 0;
}
///
/*********************************************
* Suchen einer Zeichenfolge in einem String *
*********************************************
* I: Suchstring, durchsuchter String *
* O: TRUE/FALSE : gefunden/nicht gefunden *
*********************************************/
/// "StringSearch"
BOOL StringSearch(STRPTR string1, STRPTR string2)
{
UWORD stelle, len1, len2;
len1 = strlen(string1);
len2 = strlen(string2);
for(stelle = 0; stelle < len1; stelle++)
{
if (strncmp(string1+stelle, string2, len2) == 0)
return TRUE; /* Gefunden! */
}
return FALSE;
}
///
/******************************************
* Funktionstasten auswerten *
******************************************
* I: Tastencode *
* O: --- *
******************************************/
/// "DoFKey"
VOID DoFKey(UWORD code)
{
switch(code)
{
default:
break;
}
}
///
/******************************************
* Datum / Zeit aufbereiten *
******************************************
* I: Ergebnis-String, Offset, Festzeit *
* O: Sekunden online *
******************************************/
/// "MakeTime"
ULONG MakeTime(STRPTR buff, time_t difftime, time_t fixtime)
{
time_t just;
struct tm *zt;
/* Wenn fixtime > 0, dann diesen Wert als Zeit nehmen, sonst akt. Zeit */
if (fixtime)
just = fixtime;
else
just = time(NULL);
/* Wenn difftime > 0, dann Differenz berechnen */
if (difftime)
just -= difftime;
if (buff)
{
if (difftime)
{
UBYTE h = just / 3600;
UBYTE m = (just - h * 3600) / 60;
UBYTE s = just % 60;
sprintf(buff, "--.--.-- %02d:%02d:%02d", h, m, s);
}
else
{
zt = localtime(&just);
sprintf(buff, "%02d.%02d.%02d %02d:%02d:%02d", zt->tm_mday, zt->tm_mon+1, zt->tm_year, zt->tm_hour, zt->tm_min, zt->tm_sec);
}
}
return (ULONG)just;
}
///
/**********************
* Cursor einschalten *
**********************
* I: --- *
* O: --- *
**********************/
/// "CursorOn"
VOID CursorOn(VOID)
{
if (!KMS_LC->Cursor && (KMS_LC->Device & DEV_CONSOLE))
{
Print("\33[ p", PF_NOLF|PF_NOBRK);
KMS_LC->Cursor = TRUE;
}
}
///
/**********************
* Cursor ausschalten *
**********************
* I: --- *
* O: --- *
**********************/
/// "CursorOff"
VOID CursorOff(VOID)
{
if (KMS_LC->Cursor && (KMS_LC->Device & DEV_CONSOLE))
{
Print("\33[0 p", PF_NOLF|PF_NOBRK);
KMS_LC->Cursor = FALSE;
}
}
///
/******************************************
* Ein Zeichen aus *
* KMS_LC->Session.InputBuffer entfernen, *
* Rest entsprechend nachziehen *
******************************************
* I: Zeichenposition *
* O: --- *
******************************************/
/// "DelInputChar"
VOID DelInputChar(UWORD pos)
{
while(KMS_LC->Session.InputBuffer[pos])
KMS_LC->Session.InputBuffer[pos] = KMS_LC->Session.InputBuffer[++pos];
}
///
/******************************************
* Ein Zeichen in *
* KMS_LC->Session.InputBuffer einfuegen *
* Rest entsprechend vorschieben *
******************************************
* I: Zeichenposition *
* O: --- *
******************************************/
/// "InsInputChar"
VOID InsInputChar(UWORD pos)
{
UWORD b = strlen(KMS_LC->Session.InputBuffer) + 1;
KMS_LC->Session.InputBuffer[b--] = '\0';
while(b != pos)
KMS_LC->Session.InputBuffer[b] = KMS_LC->Session.InputBuffer[--b];
}
///
/******************************************
* Chat Ausgabe *
******************************************
* I: Zeichenkette, Flags *
* O: --- *
******************************************/
/// "ChatOut"
VOID ChatOut(STRPTR text, UWORD flags)
{
TEXT target[LEN_NUMBER+4+1];
TEXT command[LEN_REXXBUFF+1];
struct KMSNode *member = KMSBase->MemberList.mlh_Head;
if (flags & CO_NOPROMPT)
sprintf(command, "OUT CHAT TEXT %s\r\n", text);
else if (flags & CO_EMOTE)
sprintf(command, "OUT CHAT TEXT %s %s\r\n", KMS_LC->Session.CurrentUser->UserData.Name, text);
else
sprintf(command, "OUT CHAT TEXT %s: %s\r\n", KMS_LC->Session.CurrentUser->UserData.Name, text);
TakeMSem(FALSE);
while(member->Node.mln_Succ)
{
if ((member->LCPtr->ID != KMS_LC->ID || (flags & CO_METOO)) && member->LCPtr->Session.CommMode == CM_CHAT)
{
if (!stricmp(KMS_LC->Session.ChatChannel, member->LCPtr->Session.ChatChannel))
{
sprintf(target, "KMS.%d", member->LCPtr->ID);
sendRexxCmd(command, NULL, NULL, NULL, NULL, target);
}
}
member = member->Node.mln_Succ;
}
DropMSem();
}
///
/*************************
* Standardfehlerausgabe *
*************************
*** I: Text *
*** O: --- *
*************************/
/// "Error"
VOID Error(STRPTR str)
{
if (StdErr && str)
{
Write(StdErr, str, strlen(str));
Write(StdErr, "\n", 1);
}
}
///